package chen.videoedit;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
 * 音频播放
 */
public class AudioPlayActivity extends BasisActivity {
    private int totalRawSize = 0;
    @Override
    public int setlayoutResID() {
        return R.layout.activity_audio_play;
    }
    @Override
    public void initialView(Bundle arg0) {
        findViewById(R.id.activity_audio_play_bt).setOnClickListener(this);
    }
    @Override
    public void setActivity() {
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.activity_audio_play_bt:
                MtThread thread = new MtThread();
                thread.start();
                break;
        }
    }

    private class MtThread extends Thread {
        @Override
        public void run() {
            prepares(Environment.getExternalStorageDirectory() + "/audio.mp3");//;
        }
    }


    private void prepares(String path) {
        //文件提取
        MediaExtractor extractor = new MediaExtractor();
        try {
            extractor.setDataSource(path);
        } catch (IOException e) {
            extractor.release();
            extractor = null;
        }
        if (extractor == null) return;

        MediaFormat format = null;
        String mime = null;
        int track = 0;
        int trackCount = extractor.getTrackCount();
        for (int i = 0; i < trackCount; i++) {
            MediaFormat f = extractor.getTrackFormat(i);
            String m = f.getString(MediaFormat.KEY_MIME);
            if (m.startsWith("audio/")) {
                track = i;//音轨
                format = f;//音轨格式
                mime = m;
            }
        }
        extractor.selectTrack(track);

        //初始化解码器
        if (format == null) return;
        MediaCodec mediaCodec = null;
        try {
            mediaCodec = MediaCodec.createDecoderByType(mime);
        } catch (IOException e) {
            mediaCodec.stop();
            mediaCodec.release();
            mediaCodec = null;
        }

        mediaCodec.configure(format, null, null, 0);
        mediaCodec.start();
        //初始化音频播放

        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
        //音频播放缓冲区大小
        int min_buf_size = AudioTrack.getMinBufferSize(sampleRate, (channelCount == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO), AudioFormat.ENCODING_PCM_16BIT);
        int max_input_size = 0;
        if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE))
            max_input_size = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
        int mAudioInputBufSize = min_buf_size > 0 ? min_buf_size * 4 : max_input_size;//音频播放缓冲区大小是否正确
        if (mAudioInputBufSize > max_input_size && max_input_size != 0)
            mAudioInputBufSize = max_input_size;
        AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,//音频类型
                sampleRate,//采样率
                (channelCount == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO),//音频通道设置
                AudioFormat.ENCODING_PCM_16BIT,//音频数据格式
                mAudioInputBufSize,//音频播放缓冲区大小
                AudioTrack.MODE_STREAM//流或静态缓冲区
        );
        try {
            audioTrack.play();
        } catch (final Exception e) {
            audioTrack.release();
            audioTrack = null;
        }

        play(extractor, mediaCodec, audioTrack);
    }


    /**
     * 播放音频
     *
     * @param extractor
     * @param mediaCodec
     * @param audioTrack
     */
    private void play(MediaExtractor extractor, MediaCodec mediaCodec, AudioTrack audioTrack) {


        ByteBuffer[] decode_input = mediaCodec.getInputBuffers();//MediaCodec在此ByteBuffer[]中获取输入数据
        ByteBuffer[] decode_output = mediaCodec.getOutputBuffers();//MediaCodec将解码后的数据放到此ByteBuffer[]中 我们可以直接在这里面得到PCM数据
        MediaCodec.BufferInfo decode_info = new MediaCodec.BufferInfo();//用于描述解码得到的byte[]数据的相关信息

        extractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);//从头开始解析

        while (true) {
            int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);//获取
            if (inputBufferIndex < 0) break;
            ByteBuffer inbuffer = decode_input[inputBufferIndex];
            inbuffer.clear();
            int sampleSize = extractor.readSampleData(inbuffer, 0);//读取数据放入解码器
            if (sampleSize < 0) break;//sampleSize读取完成
                mediaCodec.queueInputBuffer(inputBufferIndex, 0, sampleSize, 0, 0);//通知解码器数据放入
                extractor.advance();//读取下一步

            int outputBufferIndex = mediaCodec.dequeueOutputBuffer(decode_info, 1000);//获取解码数据
            while (outputBufferIndex >= 0) {
                ByteBuffer outputBuffer = decode_output[outputBufferIndex];//获取解析数据
                if (decode_info.size != 0) {
                    outputBuffer.position(decode_info.offset);
                    outputBuffer.limit(decode_info.offset + decode_info.size);
                    byte[] data = new byte[decode_info.size];
                    outputBuffer.get(data);
                    totalRawSize += data.length;
                  //  audioTrack.write(data, 0, decode_info.size);


                }
                mediaCodec.releaseOutputBuffer(outputBufferIndex, false);//此操作一定要做，不然MediaCodec用完所有的Buffer后 将不能向外输出数据
                outputBufferIndex = mediaCodec.dequeueOutputBuffer(decode_info, 1000);
            }
        }
        Log.e("lll", "释放");
        extractor.release();
        extractor = null;
        mediaCodec.stop();
        mediaCodec.release();
        mediaCodec = null;
        audioTrack.stop();
        audioTrack.release();
        audioTrack = null;

    }

}
